package org.ricks.utils;

import org.ricks.common.FastByteArrayOutputStream;
import org.ricks.common.UtilException;
import org.ricks.common.bean.ArrayUtil;
import org.ricks.common.bean.IterUtil;
import org.ricks.common.conf.Node;
import org.ricks.common.convert.Convert;
import org.ricks.common.json.NumberUtil;

import java.io.*;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.function.Supplier;

/**
 * @author chenwei
 * @Title:
 * @Package
 * @Description:
 * @date 2020/8/717:18
 */
public class ObjectUtil {

    /**
     * 比较两个对象是否相等，此方法是 {@link #equal(Object, Object)}的别名方法。<br>
     * 相同的条件有两个，满足其一即可：<br>
     * <ol>
     * <li>obj1 == null &amp;&amp; obj2 == null</li>
     * <li>obj1.equals(obj2)</li>
     * <li>如果是BigDecimal比较，0 == obj1.compareTo(obj2)</li>
     * </ol>
     *
     * @param obj1 对象1
     * @param obj2 对象2
     * @return 是否相等
     * @see #equal(Object, Object)
     * @since 5.4.3
     */
    public static boolean equals(Object obj1, Object obj2) {
        return equal(obj1, obj2);
    }

    /**
     * 比较两个对象是否相等。<br>
     * 相同的条件有两个，满足其一即可：<br>
     * <ol>
     * <li>obj1 == null &amp;&amp; obj2 == null</li>
     * <li>obj1.equals(obj2)</li>
     * <li>如果是BigDecimal比较，0 == obj1.compareTo(obj2)</li>
     * </ol>
     *
     * @param obj1 对象1
     * @param obj2 对象2
     * @return 是否相等
     * @see Objects#equals(Object, Object)
     */
    public static boolean equal(Object obj1, Object obj2) {
        if (obj1 instanceof BigDecimal && obj2 instanceof BigDecimal) {
            return NumberUtil.equals((BigDecimal) obj1, (BigDecimal) obj2);
        }
        return Objects.equals(obj1, obj2);
    }

    /**
     * 比较两个对象是否不相等。<br>
     *
     * @param obj1 对象1
     * @param obj2 对象2
     * @return 是否不等
     * @since 3.0.7
     */
    public static boolean notEqual(Object obj1, Object obj2) {
        return false == equal(obj1, obj2);
    }

    /**
     * 计算对象长度，如果是字符串调用其length函数，集合类调用其size函数，数组调用其length属性，其他可遍历对象遍历计算长度<br>
     * 支持的类型包括：
     * <ul>
     * <li>CharSequence</li>
     * <li>Map</li>
     * <li>Iterator</li>
     * <li>Enumeration</li>
     * <li>Array</li>
     * </ul>
     *
     * @param obj 被计算长度的对象
     * @return 长度
     */
    public static int length(Object obj) {
        if (obj == null) {
            return 0;
        }
        if (obj instanceof CharSequence) {
            return ((CharSequence) obj).length();
        }
        if (obj instanceof Collection) {
            return ((Collection<?>) obj).size();
        }
        if (obj instanceof Map) {
            return ((Map<?, ?>) obj).size();
        }

        int count;
        if (obj instanceof Iterator) {
            Iterator<?> iter = (Iterator<?>) obj;
            count = 0;
            while (iter.hasNext()) {
                count++;
                iter.next();
            }
            return count;
        }
        if (obj instanceof Enumeration) {
            Enumeration<?> enumeration = (Enumeration<?>) obj;
            count = 0;
            while (enumeration.hasMoreElements()) {
                count++;
                enumeration.nextElement();
            }
            return count;
        }
        if (obj.getClass().isArray() == true) {
            return Array.getLength(obj);
        }
        return -1;
    }

    /**
     * 对象中是否包含元素<br>
     * 支持的对象类型包括：
     * <ul>
     * <li>String</li>
     * <li>Collection</li>
     * <li>Map</li>
     * <li>Iterator</li>
     * <li>Enumeration</li>
     * <li>Array</li>
     * </ul>
     *
     * @param obj     对象
     * @param element 元素
     * @return 是否包含
     */
    public static boolean contains(Object obj, Object element) {
        if (obj == null) {
            return false;
        }
        if (obj instanceof String) {
            if (element == null) {
                return false;
            }
            return ((String) obj).contains(element.toString());
        }
        if (obj instanceof Collection) {
            return ((Collection<?>) obj).contains(element);
        }
        if (obj instanceof Map) {
            return ((Map<?, ?>) obj).containsValue(element);
        }

        if (obj instanceof Iterator) {
            Iterator<?> iter = (Iterator<?>) obj;
            while (iter.hasNext()) {
                Object o = iter.next();
                if (equal(o, element)) {
                    return true;
                }
            }
            return false;
        }
        if (obj instanceof Enumeration) {
            Enumeration<?> enumeration = (Enumeration<?>) obj;
            while (enumeration.hasMoreElements()) {
                Object o = enumeration.nextElement();
                if (equal(o, element)) {
                    return true;
                }
            }
            return false;
        }
        if (obj.getClass().isArray() == true) {
            int len = Array.getLength(obj);
            for (int i = 0; i < len; i++) {
                Object o = Array.get(obj, i);
                if (equal(o, element)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 检查对象是否为null<br>
     * 判断标准为：
     *
     * <pre>
     * 1. == null
     * 2. equals(null)
     * </pre>
     *
     * @param obj 对象
     * @return 是否为null
     */
    public static boolean isNull(Object obj) {
        //noinspection ConstantConditions
        return null == obj || obj.equals(null);
    }

    /**
     * 检查对象是否不为null
     *
     * @param obj 对象
     * @return 是否为null
     */
    public static boolean isNotNull(Object obj) {
        //noinspection ConstantConditions
        return null != obj && false == obj.equals(null);
    }

    /**
     * 判断指定对象是否为空，支持：
     *
     * <pre>
     * 1. CharSequence
     * 2. Map
     * 3. Iterable
     * 4. Iterator
     * 5. Array
     * </pre>
     *
     * @param obj 被判断的对象
     * @return 是否为空，如果类型不支持，返回false
     * @since 4.5.7
     */
    @SuppressWarnings("rawtypes")
    public static boolean isEmpty(Object obj) {
        if (null == obj) {
            return true;
        }

        if (obj instanceof CharSequence) {
            return StrUtil.isEmpty((CharSequence) obj);
        } else if (obj instanceof Map) {
            return MapUtil.isEmpty((Map) obj);
        } else if (obj instanceof Iterable) {
            return IterUtil.isEmpty((Iterable) obj);
        } else if (obj instanceof Iterator) {
            return IterUtil.isEmpty((Iterator) obj);
        } else if (ArrayUtil.isArray(obj)) {
            return ArrayUtil.isEmpty(obj);
        }

        return false;
    }

    /**
     * 判断指定对象是否为非空，支持：
     *
     * <pre>
     * 1. CharSequence
     * 2. Map
     * 3. Iterable
     * 4. Iterator
     * 5. Array
     * </pre>
     *
     * @param obj 被判断的对象
     * @return 是否为空，如果类型不支持，返回true
     * @since 4.5.7
     */
    public static boolean isNotEmpty(Object obj) {
        return false == isEmpty(obj);
    }

    /**
     * 如果给定对象为{@code null}返回默认值
     *
     * <pre>
     * ObjectUtil.defaultIfNull(null, null)      = null
     * ObjectUtil.defaultIfNull(null, "")        = ""
     * ObjectUtil.defaultIfNull(null, "zz")      = "zz"
     * ObjectUtil.defaultIfNull("abc", *)        = "abc"
     * ObjectUtil.defaultIfNull(Boolean.TRUE, *) = Boolean.TRUE
     * </pre>
     *
     * @param <T>          对象类型
     * @param object       被检查对象，可能为{@code null}
     * @param defaultValue 被检查对象为{@code null}返回的默认值，可以为{@code null}
     * @return 被检查对象为{@code null}返回默认值，否则返回原值
     * @since 3.0.7
     */
    public static <T> T defaultIfNull(final T object, final T defaultValue) {
        return (null != object) ? object : defaultValue;
    }


    /**
     * 如果给定对象为{@code null} 返回默认值, 如果不为null 返回自定义handle处理后的返回值
     *
     * @param source       Object 类型对象
     * @param handle       自定义的处理方法
     * @param defaultValue 默认为空的返回值
     * @param <T>          被检查对象为{@code null}返回默认值，否则返回自定义handle处理后的返回值
     * @return 处理后的返回值
     * @since 5.4.6
     */
    public static <T> T defaultIfNull(Object source, Supplier<? extends T> handle, final T defaultValue) {
        if (Objects.nonNull(source)) {
            return handle.get();
        }
        return defaultValue;
    }

    /**
     * 如果给定对象为{@code null}或者""返回默认值, 否则返回自定义handle处理后的返回值
     *
     * @param str          String 类型
     * @param handle       自定义的处理方法
     * @param defaultValue 默认为空的返回值
     * @param <T>          被检查对象为{@code null}或者 ""返回默认值，否则返回自定义handle处理后的返回值
     * @return 处理后的返回值
     * @since 5.4.6
     */
    public static <T> T defaultIfEmpty(String str, Supplier<? extends T> handle, final T defaultValue) {
        if (StrUtil.isNotEmpty(str)) {
            return handle.get();
        }
        return defaultValue;
    }

    /**
     * 如果给定对象为{@code null}或者 "" 返回默认值
     *
     * <pre>
     * ObjectUtil.defaultIfEmpty(null, null)      = null
     * ObjectUtil.defaultIfEmpty(null, "")        = ""
     * ObjectUtil.defaultIfEmpty("", "zz")      = "zz"
     * ObjectUtil.defaultIfEmpty(" ", "zz")      = " "
     * ObjectUtil.defaultIfEmpty("abc", *)        = "abc"
     * </pre>
     *
     * @param <T>          对象类型（必须实现CharSequence接口）
     * @param str          被检查对象，可能为{@code null}
     * @param defaultValue 被检查对象为{@code null}或者 ""返回的默认值，可以为{@code null}或者 ""
     * @return 被检查对象为{@code null}或者 ""返回默认值，否则返回原值
     * @since 5.0.4
     */
    public static <T extends CharSequence> T defaultIfEmpty(final T str, final T defaultValue) {
        return StrUtil.isEmpty(str) ? defaultValue : str;
    }

    /**
     * 如果给定对象为{@code null}或者""或者空白符返回默认值
     *
     * <pre>
     * ObjectUtil.defaultIfEmpty(null, null)      = null
     * ObjectUtil.defaultIfEmpty(null, "")        = ""
     * ObjectUtil.defaultIfEmpty("", "zz")      = "zz"
     * ObjectUtil.defaultIfEmpty(" ", "zz")      = "zz"
     * ObjectUtil.defaultIfEmpty("abc", *)        = "abc"
     * </pre>
     *
     * @param <T>          对象类型（必须实现CharSequence接口）
     * @param str          被检查对象，可能为{@code null}
     * @param defaultValue 被检查对象为{@code null}或者 ""或者空白符返回的默认值，可以为{@code null}或者 ""或者空白符
     * @return 被检查对象为{@code null}或者 ""或者空白符返回默认值，否则返回原值
     * @since 5.0.4
     */
    public static <T extends CharSequence> T defaultIfBlank(final T str, final T defaultValue) {
        return StrUtil.isBlank(str) ? defaultValue : str;
    }

    /**
     * 克隆对象<br>
     * 如果对象实现Cloneable接口，调用其clone方法<br>
     * 如果实现Serializable接口，执行深度克隆<br>
     * 否则返回<code>null</code>
     *
     * @param <T> 对象类型
     * @param obj 被克隆对象
     * @return 克隆后的对象
     */
    public static <T> T clone(T obj) {
        T result = ArrayUtil.clone(obj);
        if (null == result) {
            if (obj instanceof Cloneable) {
                result = ReflectUtil.invoke(obj, "clone");
            } else {
                result = cloneByStream(obj);
            }
        }
        return result;
    }

    /**
     * 返回克隆后的对象，如果克隆失败，返回原对象
     *
     * @param <T> 对象类型
     * @param obj 对象
     * @return 克隆后或原对象
     */
    public static <T> T cloneIfPossible(final T obj) {
        T clone = null;
        try {
            clone = clone(obj);
        } catch (Exception e) {
            // pass
        }
        return clone == null ? obj : clone;
    }

    /**
     * 序列化后拷贝流的方式克隆<br>
     * 对象必须实现Serializable接口
     *
     * @param <T> 对象类型
     * @param obj 被克隆对象
     * @return 克隆后的对象
     * @throws UtilException IO异常和ClassNotFoundException封装
     */
    @SuppressWarnings("unchecked")
    public static <T> T cloneByStream(T obj) {
        if (false == (obj instanceof Serializable)) {
            return null;
        }
        final FastByteArrayOutputStream byteOut = new FastByteArrayOutputStream();
        ObjectOutputStream out = null;
        try {
            out = new ObjectOutputStream(byteOut);
            out.writeObject(obj);
            out.flush();
            final ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(byteOut.toByteArray()));
            return (T) in.readObject();
        } catch (Exception e) {
            throw new UtilException(e);
        } finally {
            IoUtil.close(out);
        }
    }

    /**
     * 序列化<br>
     * 对象必须实现Serializable接口
     *
     * @param <T> 对象类型
     * @param obj 要被序列化的对象
     * @return 序列化后的字节码
     */
    public static <T> byte[] serialize(T obj) {
        if (false == (obj instanceof Serializable)) {
            return null;
        }
        final FastByteArrayOutputStream byteOut = new FastByteArrayOutputStream();
        IoUtil.writeObjects(byteOut, false, (Serializable) obj);
        return byteOut.toByteArray();
    }

    /**
     * 反序列化<br>
     * 对象必须实现Serializable接口
     *
     * <p>
     * 注意！！！ 此方法不会检查反序列化安全，可能存在反序列化漏洞风险！！！
     * </p>
     *
     * @param <T>   对象类型
     * @param bytes 反序列化的字节码
     * @return 反序列化后的对象
     */
    public static <T> T deserialize(byte[] bytes) {
        return IoUtil.readObj(new ByteArrayInputStream(bytes));
    }

    /**
     * 反序列化<br>
     * 对象必须实现Serializable接口
     *
     * @param <T>   对象类型
     * @param bytes 反序列化的字节码
     * @return 反序列化后的对象
     * @see #deserialize(byte[])
     * @deprecated 请使用 {@link #deserialize(byte[])}
     */
    @Deprecated
    public static <T> T unserialize(byte[] bytes) {
        return deserialize(bytes);
    }

    /**
     * 是否为基本类型，包括包装类型和非包装类型
     *
     * @param object 被检查对象
     * @return 是否为基本类型
     * @see ClassUtil#isBasicType(Class)
     */
    public static boolean isBasicType(Object object) {
        return ClassUtil.isBasicType(object.getClass());
    }

    /**
     * 检查是否为有效的数字<br>
     * 检查Double和Float是否为无限大，或者Not a Number<br>
     * 非数字类型和Null将返回true
     *
     * @param obj 被检查类型
     * @return 检查结果，非数字类型和Null将返回true
     */
    public static boolean isValidIfNumber(Object obj) {
        if (obj instanceof Number) {
            return NumberUtil.isValidNumber((Number) obj);
        }
        return true;
    }

    /**
     * {@code null}安全的对象比较，{@code null}对象排在末尾
     *
     * @param <T> 被比较对象类型
     * @param c1  对象1，可以为{@code null}
     * @param c2  对象2，可以为{@code null}
     * @return 比较结果，如果c1 &lt; c2，返回数小于0，c1==c2返回0，c1 &gt; c2 大于0
     * @see Comparator#compare(Object, Object)
     * @since 3.0.7
     */
    public static <T extends Comparable<? super T>> int compare(T c1, T c2) {
        return CompareUtil.compare(c1, c2);
    }

    /**
     * {@code null}安全的对象比较
     *
     * @param <T>         被比较对象类型
     * @param c1          对象1，可以为{@code null}
     * @param c2          对象2，可以为{@code null}
     * @param nullGreater 当被比较对象为null时是否排在前面
     * @return 比较结果，如果c1 &lt; c2，返回数小于0，c1==c2返回0，c1 &gt; c2 大于0
     * @see Comparator#compare(Object, Object)
     * @since 3.0.7
     */
    public static <T extends Comparable<? super T>> int compare(T c1, T c2, boolean nullGreater) {
        return CompareUtil.compare(c1, c2, nullGreater);
    }

    /**
     * 获得给定类的第一个泛型参数
     *
     * @param obj 被检查的对象
     * @return {@link Class}
     * @since 3.0.8
     */
    public static Class<?> getTypeArgument(Object obj) {
        return getTypeArgument(obj, 0);
    }

    /**
     * 获得给定类的第一个泛型参数
     *
     * @param obj   被检查的对象
     * @param index 泛型类型的索引号，即第几个泛型类型
     * @return {@link Class}
     * @since 3.0.8
     */
    public static Class<?> getTypeArgument(Object obj, int index) {
        return ClassUtil.getTypeArgument(obj.getClass(), index);
    }

    /**
     * 将Object转为String<br>
     * 策略为：
     * <pre>
     *  1、null转为"null"
     *  2、调用Convert.toStr(Object)转换
     * </pre>
     *
     * @param obj Bean对象
     * @return Bean所有字段转为Map后的字符串
     * @since 3.2.0
     */
    public static String toString(Object obj) {
        if (null == obj) {
            return StrUtil.NULL;
        }
        if (obj instanceof Map) {
            return obj.toString();
        }

        return Convert.toStr(obj);
    }

    /**
     * 存在多少个{@code null}或空对象，通过{@link ObjectUtil#isEmpty(Object)} 判断元素
     *
     * @param objs 被检查的对象,一个或者多个
     * @return 存在{@code null}的数量
     */
    public static int emptyCount(Object... objs) {
        return ArrayUtil.emptyCount(objs);
    }

    /**
     * 是否存在{@code null}或空对象，通过{@link ObjectUtil#isEmpty(Object)} 判断元素
     *
     * @param objs 被检查对象
     * @return 是否存在
     */
    public static boolean hasEmpty(Object... objs) {
        return ArrayUtil.hasEmpty(objs);
    }

    /**
     * 是否全都为{@code null}或空对象，通过{@link ObjectUtil#isEmpty(Object)} 判断元素
     *
     * @param objs 被检查的对象,一个或者多个
     * @return 是否都为空
     */
    public static boolean isAllEmpty(Object... objs) {
        return ArrayUtil.isAllEmpty(objs);
    }

    /**
     * 是否全都不为{@code null}或空对象，通过{@link ObjectUtil#isEmpty(Object)} 判断元素
     *
     * @param objs 被检查的对象,一个或者多个
     * @return 是否都不为空
     */
    public static boolean isAllNotEmpty(Object... objs) {
        return ArrayUtil.isAllNotEmpty(objs);
    }

    //deep clone except classes not implement clonable
    public static Object deepClone(Object o) throws IOException, ClassNotFoundException {
        ByteArrayOutputStream bo = new ByteArrayOutputStream();
        ObjectOutputStream oo = new ObjectOutputStream(bo);
        oo.writeObject(o);
        // read from the stream
        ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
        ObjectInputStream oi = new ObjectInputStream(bi);
        return (oi.readObject());
    }

    //deep copy for multi-level map
    public static Object deepCopy(Object o) {

        if (o instanceof String
                || o instanceof Integer
                || o instanceof Float
                || o instanceof Double
                || o instanceof Boolean) {
            return o;
        }

        Map<String, Object> ret = new HashMap<>();
        LinkedBlockingQueue<Node> queue = new LinkedBlockingQueue<>();
        queue.offer(new Node((Map<String, Object>) o, ret));

        while (!queue.isEmpty()) {
            Node node = queue.poll();
            Map<String, Object> nodeRes = node.getRes();
            Map<String, Object> nodeSource = node.getSource();
            nodeRes.forEach((key, value) -> {
                if (value instanceof String
                        || value instanceof Integer
                        || value instanceof Float
                        || value instanceof Double
                        || value instanceof Boolean) {
                    nodeSource.put(key, value);
                } else {
                    Map<String, Object> tmp = new HashMap<>();
                    nodeSource.put(key, tmp);
                    queue.offer(new Node((Map<String, Object>) nodeRes.get(key), tmp));
                }
            });
        }

        return ret;
    }


    /**
     * 获取某个对象某些字段的Map
     * @param obj
     */
    public static Map<String,String> getMap(Object obj,String ...strings){
        Map<String,String> map = new HashMap<String, String>();
        boolean addAllFields = false;
        if(strings==null||strings.length==0){
            addAllFields=true;
        }
        if(obj!=null){
            Field[] fields = getAllFields(obj);
            for(Field field:fields){
                field.setAccessible(true);
                try {
                    boolean needsAddToMap = false;
                    for(String s:strings){
                        if(field.getName().equals(s)){
                            needsAddToMap=true;
                            break;
                        }
                    }
                    if(needsAddToMap||addAllFields){
                        map.put(field.getName(), getFieldsValueStr(obj, field.getName()));
                    }
                }catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        if(!addAllFields&&strings.length!=map.size()){
            return new HashMap<String, String>();
        }
        return map;
    }
    private static Field[] getAllFields(Object obj){
        Class<?> clazz = obj.getClass();
        Field[] rt=null;
        for(;clazz!=Object.class;clazz=clazz.getSuperclass()){
            Field[] tmp = clazz.getDeclaredFields();
            rt = combine(rt, tmp);
        }
        return rt;
    }
    private static Field[] combine(Field[] a, Field[] b){
        if(a==null){
            return b;
        }
        if(b==null){
            return a;
        }
        Field[] rt = new Field[a.length+b.length];
        System.arraycopy(a, 0, rt, 0, a.length);
        System.arraycopy(b, 0, rt, a.length, b.length);
        return rt;
    }

    public static Object getFieldsValueObj(Object obj,String fieldName){
        Field field = getDeclaredField(obj,fieldName);
        field.setAccessible(true);
        try {
            return field.get(obj);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String getFieldsValueStr(Object obj,String fieldName){
        Object o = getFieldsValueObj(obj, fieldName);
        return getObjectString(o);
    }

    public static String getObjectString(Object object){
        //如果为空则输出为""
        if(object == null){
            return "";
        }
        if(object instanceof Date){
            return TimeUtils.dateToString((Date) object);
        }
        return object.toString();
    }


    public static Map<String, String> getTransferMap(Map<String, Object> map){
        Map<String, String> transferMap = new HashMap<>();
        for(Map.Entry<String, Object> entry: map.entrySet()){
            transferMap.put(entry.getKey(), getObjectString(entry.getValue()));
        }
        return transferMap;
    }

    public static String getFieldsValueStr(Object obj,String[] fieldName){
        Map<String,String> keyMap=getMap(obj, fieldName);
        StringBuilder sb=new StringBuilder();
        for(int i = 0; i < fieldName.length;i++){
            String keyName=fieldName[i];
            sb.append(keyMap.get(keyName));
            if(i == fieldName.length - 1){
                break;
            }
            sb.append('#');
        }
        return sb.toString();
    }


    private static Field getDeclaredField(Object object, String fieldName){
        Class<?> clazz = object.getClass();
        for(; clazz != Object.class ; clazz = clazz.getSuperclass()) {
            try {
                return clazz.getDeclaredField(fieldName);
            } catch (Exception e) {
            }
        }
        return null;
    }
    private static Method getSetMethod(Object object, String method, Class<?> fieldType){
        Class<?> clazz=object.getClass();
        for(;clazz!=Object.class;clazz=clazz.getSuperclass()){
            try {
                return clazz.getDeclaredMethod(method, fieldType);
            } catch (Exception e) {
            }
        }
        return null;
    }
    @SuppressWarnings("unchecked")
    public static <T> T getObjFromMap(Map<String,String> map, Object obj){
        try {
            for(Map.Entry<String, String> stringStringEntry : map.entrySet()){
                String value = stringStringEntry.getValue();
                //如果为空放弃，默认设置为空
                if(StrUtil.isBlank(value)){
                    continue;
                }
                Field field=getDeclaredField(obj, stringStringEntry.getKey());
                Method method=getSetMethod(obj, buildSetMethod(stringStringEntry.getKey()), field.getType());
                if(field.getType()==Integer.class||field.getType()==int.class){
                    method.invoke(obj, Integer.parseInt(stringStringEntry.getValue()));
                }else if(field.getType()==Boolean.class||field.getType()==boolean.class){
                    method.invoke(obj, Boolean.parseBoolean(stringStringEntry.getValue()));
                }else if(field.getType()==Long.class||field.getType()==long.class){
                    method.invoke(obj, Long.parseLong(stringStringEntry.getValue()));
                }else if(field.getType()==Float.class||field.getType()==float.class){
                    method.invoke(obj, Float.parseFloat(stringStringEntry.getValue()));
                }else if(field.getType()==Double.class||field.getType()==double.class){
                    method.invoke(obj, Double.parseDouble(stringStringEntry.getValue()));
                }else if(field.getType()==Byte.class||field.getType()==byte.class){
                    method.invoke(obj, Byte.parseByte(stringStringEntry.getValue()));
                }else if(field.getType()==Short.class||field.getType()==short.class){
                    method.invoke(obj, Short.parseShort(stringStringEntry.getValue()));
                }else if(field.getType()==String.class){
                    method.invoke(obj, stringStringEntry.getValue());
                }else if(field.getType()==Date.class){
                    method.invoke(obj, TimeUtils.stringToDate(stringStringEntry.getValue()));
                }else if(field.getType()== Timestamp.class){
                    method.invoke(obj, TimeUtils.stringtoTimestamp(stringStringEntry.getValue()));
                }
            }
            return (T)obj;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 从map里构造出一个实例对象
     * @param map
     * @param clazz
     * @return
     */
    public static <T> T getObjFromMap(Map<String,String> map,Class<?> clazz){
        try {
            Object obj=clazz.newInstance();
            return getObjFromMap(map, obj);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    private static String buildSetMethod(String fieldName){
        StringBuilder sb=new StringBuilder("set");
        if(fieldName.length()>1){
            String first=fieldName.substring(0, 1);
            String next=fieldName.substring(1);
            sb.append(first.toUpperCase()).append(next);
        }else{
            sb.append(fieldName.toUpperCase());
        }
        return sb.toString();
    }
    /**
     * 判断某个list是否没有数据
     * @param <T>
     * @param list
     * @return
     */
    public static <T> boolean isEmpityList(List<T> list){
        boolean b = false;
        if(list==null||list.isEmpty()){
            b=true;
        }
        return b;
    }


    public static boolean eqOrBothNull(Object var0, Object var1) {
        if (var0 == var1) {
            return true;
        } else {
            return var0 == null ? false : var0.equals(var1);
        }
    }

    public static int hashOrZero(Object var0) {
        return var0 == null ? 0 : var0.hashCode();
    }
}
